<template>
  <view class="sign-box">
    <view class="ss-flex ss-row-center">
      <view
        class="sign-btn"
        :class="{ disabled: disabled }"
        :style="{
          '--speed': speed + 's',
          '--delay': (speed / 3).toFixed() + 's',
        }"
        @click="handleClick"
      >
        <view>{{ label }}</view>
        <view v-if="showTime" class="clock-in-time">{{ nowTime }}</view>
      </view>
    </view>
    <view class="ss-flex ss-row-center sign-tips" v-if="showTips">
      <uv-icon
        :name="near ? iconMap : iconWarn"
        size="28rpx"
        :label="near ? '已进入考勤范围' : '当前不在考勤范围内'"
        label-color="#212121"
        label-size="28rpx"
      />
    </view>
  </view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { faceVerify } from "@/request/common";
import iconMap from "@/static/sign/icon_map.png";
import iconWarn from "@/static/sign/icon_warn.png";

const props = defineProps({
  // 按钮文字
  label: {
    type: String,
    default: "打卡",
  },
  // 显示时间
  showTime: {
    type: Boolean,
    default: true,
  },
  // 禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 是否在考勤范围内
  near: {
    type: Boolean,
    default: false,
  },
  // 动画速度 单位s
  speed: {
    type: [Number, String],
    default: 3,
  },
  // 显示提示
  showTips: {
    type: Boolean,
    default: true,
  },
  // 开启认证 (需要配置AP-FaceDetectModule插件)
  auth: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(["confirm"]);

// #ifdef APP-PLUS
const n = uni.requireNativePlugin("AP-FaceDetectModule"); // 引入原生模块
// #endif
const nowDate = ref(""); // 当前日期
const nowTime = ref(""); // 当前时间
const certifyId = ref(""); // 实人认证ID

onMounted(() => {
  if (props.showTime) {
    setInterval(() => {
      getNowTime();
    }, 1000);
  }
});

// 获取当前时间
const getNowTime = () => {
  const date = new Date();
  const year = date.getFullYear();
  const month =
    date.getMonth() + 1 > 9 ? date.getMonth() + 1 : "0" + (date.getMonth() + 1);
  const day = date.getDate() > 9 ? date.getDate() : "0" + date.getDate();
  const hour = date.getHours() > 9 ? date.getHours() : "0" + date.getHours();
  const minute = date.getMinutes() > 9 ? date.getMinutes() : "0" + date.getMinutes();
  const second = date.getSeconds() > 9 ? date.getSeconds() : "0" + date.getSeconds();
  nowDate.value = `${year}-${month}-${day}`;
  nowTime.value = `${hour}:${minute}:${second}`;
};

// 签到
const handleClick = () => {
  if (!props.disabled && props.near) {
    if (props.auth) {
      // #ifdef APP-PLUS
      const user = uni.getStorageSync("userInfo");
      let data = {
        certName: user.nickName,
        certNo: user.idCard,
        certType: "IDENTITY_CARD",
        metaInfo: n.getMetaInfo(),
        model: "MULTI_ACTION",
        productCode: "ID_PRO",
      };
      faceVerify(data).then((res) => {
        console.log(res, "认证ID");
        if (res.code == 200) {
          certifyId.value = res.data.resultObject.certifyId;
          verifyC();
        }
      });
      // #endif
      // #ifdef H5
      uni.showToast({
        title: "开启实名认证（移动端生效）",
        icon: "none",
      });
      emit("confirm", nowDate.value + " " + nowTime.value);
      // #endif
    } else {
      emit("confirm", nowDate.value + " " + nowTime.value);
    }
  }
};

// 人脸验证
const verifyC = () => {
  n.verify(
    {
      certifyId: certifyId.value, //认证ID
      returnVideo: false, //是否返回视频（iOS）
      returnVideoUpload: false, //是否需要将返回视频上传到OSS（iOS）
      ext_params_key_use_video: false, //是否返回视频并上传到OSS（Android）
    },
    (v) => {
      console.log("离线验证：", v);
      // 有效验证
      if (v.code == 1000 || v.code == 2006) {
        //1000成功 2006失败
        if (v.code == 1000) {
          emit("confirm", nowDate.value + " " + nowTime.value);
        } else {
          uni.showToast({
            title: "认证失败",
            icon: "none",
          });
        }
      } else {
        const codeMsg = [
          { code: 1001, msg: "系统错误" },
          { code: 1003, msg: "验证中断" },
          { code: 2002, msg: "网络错误" },
          { code: 2003, msg: "客户端设备时间错误" },
          { code: 2006, msg: "刷脸失败" },
        ];
        if (v.code === 1001) {
          uni.showToast({
            title: "身份信息错误",
            position: "top",
          });
          return;
        }
        uni.showToast({
          title: codeMsg.find((it) => it.code === v.code)?.msg || v.code,
          position: "top",
        });
      }
    }
  );
};
</script>
<style lang="scss" scoped>
.sign-box {
  position: relative;
  height: 600rpx;
}
.sign-btn {
  --speed: "3s";
  --delay: "1s";
  position: absolute;
  top: 200rpx;
  width: 218rpx;
  height: 218rpx;
  border-radius: 50%;
  background: linear-gradient(180deg, #73eeb2 0%, #58d196 100%);
  color: #fff;
  font-size: 32rpx;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  &:active {
    background: linear-gradient(180deg, #58d196 0%, #73eeb2 100%);
  }
  view {
    z-index: 9;
  }
  &::before {
    position: absolute;
    top: 0;
    content: "";
    display: inline-block;
    width: 218rpx;
    height: 218rpx;
    border-radius: 50%;
    background: linear-gradient(180deg, #73eeb2 0%, #58d196 100%);
    animation: clockIn var(--speed) ease-in-out infinite;
  }
  &::after {
    position: absolute;
    top: 0;
    content: "";
    display: inline-block;
    width: 218rpx;
    height: 218rpx;
    border-radius: 50%;
    background: linear-gradient(180deg, #73eeb2 0%, #58d196 100%);
    animation: clockIn var(--speed) ease-in-out infinite var(--delay);
  }

  .clock-in-time {
    font-size: 28rpx;
    margin-top: 10rpx;
  }
}
.disabled {
  background: linear-gradient(180deg, #e1e1e1 0%, #9e9e9e 100%);
  pointer-events: none;
  &::before,
  &::after {
    animation: none;
    background: linear-gradient(180deg, #e1e1e1 0%, #9e9e9e 100%);
  }
}
.sign-tips {
  position: absolute;
  bottom: 0;
  width: 100%;
}
@keyframes clockIn {
  0% {
    top: 0;
    width: 218rpx;
    height: 218rpx;
    opacity: 0.8;
  }
  100% {
    top: -40rpx;
    width: 298rpx;
    height: 298rpx;
    opacity: 0;
  }
}
</style>
